package com.kingdee.eas.custom.yq.df.app;

import java.math.BigDecimal;
import java.net.InetAddress;
import java.net.MalformedURLException;
import java.net.UnknownHostException;
import java.rmi.RemoteException;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Set;

import javax.xml.rpc.ServiceException;

import org.apache.log4j.Logger;

import com.kingdee.bos.BOSException;
import com.kingdee.bos.Context;
import com.kingdee.bos.dao.IObjectPK;
import com.kingdee.bos.dao.ormapping.ObjectUuidPK;
import com.kingdee.bos.ebservice.EBException;
import com.kingdee.bos.ebservice.EBHeader;
import com.kingdee.bos.ebservice.EBService;
import com.kingdee.bos.ebservice.EBServiceServiceLocator;
import com.kingdee.bos.ebservice.PayBody;
import com.kingdee.bos.ebservice.PaymentDetail;
import com.kingdee.bos.ebservice.QueryPayRequest;
import com.kingdee.bos.ebservice.QueryPayRequestBody;
import com.kingdee.bos.ebservice.QueryPayResponse;
import com.kingdee.bos.metadata.entity.EntityViewInfo;
import com.kingdee.bos.metadata.entity.FilterInfo;
import com.kingdee.bos.metadata.entity.FilterItemInfo;
import com.kingdee.bos.metadata.entity.SelectorItemCollection;
import com.kingdee.bos.metadata.entity.SelectorItemInfo;
import com.kingdee.bos.metadata.query.util.CompareType;
import com.kingdee.eas.basedata.assistant.AccountBankFactory;
import com.kingdee.eas.basedata.assistant.AccountBankInfo;
import com.kingdee.eas.basedata.assistant.ISettlementType;
import com.kingdee.eas.basedata.assistant.SettlementTypeFactory;
import com.kingdee.eas.basedata.assistant.SettlementTypeInfo;
import com.kingdee.eas.common.EASBizException;
import com.kingdee.eas.custom.ParameterConfigFactory;
import com.kingdee.eas.custom.ParameterConfigInfo;
import com.kingdee.eas.custom.yq.df.AuxiliaryFunctionFactory;
import com.kingdee.eas.custom.yq.df.IAuxiliaryFunction;
import com.kingdee.eas.custom.yq.df.ISubstituting;
import com.kingdee.eas.custom.yq.df.ISubstitutingEntry;
import com.kingdee.eas.custom.yq.df.SubstitutingCollection;
import com.kingdee.eas.custom.yq.df.SubstitutingEntryCollection;
import com.kingdee.eas.custom.yq.df.SubstitutingEntryFactory;
import com.kingdee.eas.custom.yq.df.SubstitutingEntryInfo;
import com.kingdee.eas.custom.yq.df.SubstitutingFactory;
import com.kingdee.eas.custom.yq.df.SubstitutingInfo;
import com.kingdee.eas.custom.yq.util.ConstantValueUtil;
import com.kingdee.eas.custom.yq.util.DateTimeUtil;
import com.kingdee.eas.eqm.common.core.util.backup.FMConstants;
import com.kingdee.eas.fm.be.BEException;
import com.kingdee.eas.fm.be.BankInterfaceTypeEnum;
import com.kingdee.eas.fm.be.BankLogFacadeFactory;
import com.kingdee.eas.fm.be.BankPayingBillStateEnum;
import com.kingdee.eas.fm.be.FmBeHelper;
import com.kingdee.eas.fm.be.IBankLogFacade;
import com.kingdee.eas.fm.be.app.BankBatchSalaryService;
import com.kingdee.eas.fm.be.app.BankFacadeHelper;
import com.kingdee.eas.fm.be.app.BankPrivateService;
import com.kingdee.eas.fm.be.app.BankServiceUtil;
import com.kingdee.eas.fm.be.ws.BankAcnt;
import com.kingdee.eas.fm.be.ws.CallerTag;
import com.kingdee.eas.fm.be.ws.PayStateInfo;
import com.kingdee.eas.fm.common.FMHelper;
import com.kingdee.util.db.SQLUtils;
/**
 * 描述：自动执行按单据同步状态方法
 * 作者：mmw
 * 创建日期：2012-10-23-下午04:33:23
 */
@SuppressWarnings({"serial","unused","unchecked","static-access"})
public class SyncSubstitutingStateByBillFacadeControllerBean extends AbstractSyncSubstitutingStateByBillFacadeControllerBean
{
	private static Logger logger =
        Logger.getLogger("com.kingdee.eas.custom.yq.df.app.SyncSubstitutingStateByBillFacadeControllerBean");
    
    /**
     * 描述：按单据同步状态自动执行任务功能，
     * 主要与手动执行的区别在于，有异常信息没有终止程序，而会继续执行其他数据
     * 作者：mmw
     * 创建日期：2012-10-19-上午10:00:50
     * @see com.kingdee.eas.custom.yq.df.app.AbstractSyncSubstitutingStateByBillFacadeControllerBean#_syncSubstitutingStateByBill(com.kingdee.bos.Context, java.util.List)
     * @param ctx
     * @param idList
     * @throws BOSException
     * @throws EASBizException
     */
	protected void _syncSubstitutingStateByBill(Context ctx)
    		throws BOSException, EASBizException {
		Date date=new Date();
    	SimpleDateFormat sdf=new SimpleDateFormat("yyyy-MM-dd 00:00:00");
    	String starttime=sdf.format(date);
		Calendar calendar=new GregorianCalendar();
		calendar.setTime(date);
		//*****  二期确定为一个月  修改人:刘鹏
//		calendar.add(calendar.MONTH, -6);//时间后退半年
		calendar.add(calendar.MONTH, -1);//时间后退一个月
		date=calendar.getTime();
		String endtime=sdf.format(date);
		//查出分录的返回银行状态为提交成功，交易未确认，提交失败，数据范围半年内
		StringBuffer sb=new StringBuffer();
//    	sb.append("/*dialect*/ select a.fid from ct_yq_substituting a ");
//    	sb.append("left join ct_yq_substitutingEntry b on a.fid=b.fparentid ");
//    	sb.append("where a.cfbillstatus='20' ");
//    	sb.append("and a.fbizdate >=to_date(?,'yyyy-mm-dd HH24:mi:ss') ");
//    	sb.append("group by a.fid");
    	
    	//2013-7-23 11:50   修改人:刘鹏  查出代发单状态为已付款&&代发单分录状态不为提交成功或提交失败的所有代发单ID   数据范围:半年
    	sb.append("/*dialect*/ select distinct a.fid from ct_yq_substituting a ");
    	sb.append("inner join ct_yq_substitutingentry b on a.fid=b.fparentid ");
    	sb.append("where a.cfbillstatus='20' and b.cfbankstatus not in(5,6) ");
    	sb.append("and a.fbizdate >=to_date(?,'yyyy-mm-dd HH24:mi:ss') ");
    	Connection conn = null;
		PreparedStatement pstmt = null;
		ResultSet rs = null;
		List listId=new ArrayList();
		try{
			conn = getConnection(ctx);
			pstmt = conn.prepareStatement(sb.toString());
			pstmt.setString(1, endtime);
			rs = pstmt.executeQuery();
			while(rs.next()){
				//获取代发单id
				String validId = rs.getString("fid");
				listId.add(validId);
			}
		}catch (Exception e) {
			logger.error("getSubstitutingId error:"+e.getLocalizedMessage(),e);//自动执行脚本不适合把异常抛至前台
		}finally {
			SQLUtils.cleanup(rs, pstmt, conn);
		}
		try {
			//调用按单据同步状态接口
			Set idSet = FMHelper.list2Set(listId);
			queryPay(ctx, "", idSet);
			//登银行日记账
			SubHelp subhelp = new SubHelp();
			subhelp.bookBatchSet(ctx, idSet);
		} catch (Exception e) {
			logger.error("ICBC ISubstituting result error:"+e.getLocalizedMessage(),e);//自动执行脚本不适合把异常抛至前台
		}
	}
	/**
	 * 描述：按单据同步状态
	 * 作者：mmw
	 * 创建日期：2012-12-5-下午01:57:50
	 * @see com.kingdee.eas.custom.yq.df.app.AbstractSubstitutingControllerBean#_queryPay(com.kingdee.bos.Context, java.lang.String, java.util.Set)
	 * @param ctx
	 * @param url
	 * @param idSet
	 * @throws BOSException
	 * @throws EASBizException
	 */
	protected void queryPay(Context ctx, String url, Set idSet)
			throws BOSException, EASBizException {
		EntityViewInfo ev = new EntityViewInfo();
		FilterInfo filter = new FilterInfo();
		filter.getFilterItems().add(new FilterItemInfo("id", new HashSet(idSet),CompareType.INCLUDE));
		ev.setFilter(filter);
		ev.getSelector().add("*");
		ev.getSelector().add("entrys.*");
		ev.getSelector().add("feeType.number");
		ev.getSelector().add("payBankNumber.*");
		ev.getSelector().add("payBankNumber.openArea.*");
		ev.getSelector().add("payBankNumber.bankInterfaceType");
		ev.getSelector().add("entrys.SettlementType.*");
		
		//根据id查出代发单集合
		SubstitutingCollection billColl = SubstitutingFactory.getLocalInstance(ctx).getSubstitutingCollection(ev);
		// 对 每一个账户循环更新
		for (int i = 0, size = billColl.size(); i < size; i++) {
			SubstitutingInfo bill = billColl.get(i);
//			if(checkEntryPayState(bill)) continue;
			String feetypeNumber=bill.getFeeType().getNumber();//收付类别
			String accNo=bill.getPayBankNumber().getBankAccountNumber();//付款账号
			try{
				String requestTime = DateTimeUtil.formatyyyyMMddHHmmss(new Date());
				busiQueryPay(ctx,bill,accNo,requestTime,feetypeNumber);
			}  catch (MalformedURLException e) {
				logger.error("ICBC ISubstituting result error:"+e.getLocalizedMessage(),e);//自动执行脚本不适合把异常抛至前台
			} catch (RemoteException e) {
				logger.error("ICBC ISubstituting result error:"+e.getLocalizedMessage(),e);//自动执行脚本不适合把异常抛至前台
			} catch (ServiceException e) {
				logger.error("ICBC ISubstituting result error:"+e.getLocalizedMessage(),e);//自动执行脚本不适合把异常抛至前台
			}
		}
	}
	/**
	 * 工行批扣结果反馈主程序
	 * @param ctx
	 * @param serialNumber 批扣账户信息
	 * @param accNo 扣款时间
	 * @param requestTime 
	 * @param feetypeNumber 
	 * @return String[] [扣款状态][扣款金额][银行返回信息]
	 */
	public void busiQueryPay(Context ctx, SubstitutingInfo bill, String accNo, String requestTime, String feetypeNumber ) throws MalformedURLException, ServiceException, RemoteException, BOSException, EASBizException{
		//该数据 的业务唯一标示Id,此值在提交银企时保存的
		if(bill.getBatchSeqID().equals("")){
			return;
		}
		String BatchSeqID=bill.getBatchSeqID().toString();//业务单据唯一标示
		String serialNumber=BatchSeqID;
		
		//代发单主表接口
		ISubstituting isub = SubstitutingFactory.getLocalInstance(ctx);
		//代发单接口
		ISubstitutingEntry isubentry = SubstitutingEntryFactory.getLocalInstance(ctx);
		
		//代发单辅助功能接口
		IAuxiliaryFunction auxiliaryFunctions=AuxiliaryFunctionFactory.getLocalInstance(ctx);
		QueryPayRequest request = new QueryPayRequest();
		QueryPayRequestBody body = new QueryPayRequestBody();
		SubHelp subhelp=new SubHelp();
		EBHeader header = new EBHeader();
		// 设置头
		header.setClientName("EAS");
		header.setClientVersion("EAS7.0");
		header.setBizType("pay");
		String paybankName=bill.getPayerBank();
		/**1.代发工资，用pay_for_salary表示（对私）；
		  *3.普通支付，用pay表示，目前用于其余用途的支付（对公对私）。
		  **/
		if(feetypeNumber.equals(ConstantValueUtil.WAGES) && paybankName.indexOf("工商")!=-1){
			//工资同行
			header.setSubBizType("pay_for_salary");
		}else if(feetypeNumber.equals(ConstantValueUtil.WAGES) && paybankName.indexOf("工商")==-1){
			//工资同行 //不为工商
			header.setSubBizType("pay");
		}else if(feetypeNumber.equals(ConstantValueUtil.WAGESN) || 
				feetypeNumber.equals(ConstantValueUtil.KINGSHIPBILLN) ||
				feetypeNumber.equals(ConstantValueUtil.REMITREFUNDBILL)||
				feetypeNumber.equals(ConstantValueUtil.KINGSHIPBILL)){
			//工资跨行-亲情1+1跨行-亲情1+1同行-代收货款
			header.setSubBizType("pay");
		}
		header.setOperationName("queryPay");	
		//CNY表示人民币，目前只支持人民币
		header.setCurrency("CNY");
		// request表示请求response表示响应
		header.setMessageType("request");
		// 格式为yyyyMMddHHmmss
		header.setRequestTime(requestTime);
		// 主账号 含义为查询帐号或付款帐号
		header.setAccNo(accNo);
		// 设置body
		// 报账号,即ERP产生的批次号
		body.setBatchSeqID(serialNumber);
		
		request.setHeader(header);
		request.setBody(body);
		logger.info("Substituting info:QueryPay BatchSeqID "+serialNumber+" is ready. Start to send!");
		String url1 = getEBServiceURL(ctx);
		java.net.URL endpoint = new java.net.URL(url1);
		EBServiceServiceLocator locator = new EBServiceServiceLocator();
		EBService service = locator.getEBService(endpoint);
		// 返回值
		QueryPayResponse response = service.queryPay(request);
		// 返回异常
		EBException exception = response.getException();
		PayBody responsebody = response.getBody();
		EBHeader responseheader = response.getHeader();
		if (exception == null) {
			logger.info("Substituting info:QueryPay BatchSeqID "+serialNumber+ " send success!");
			boolean flag = false;
			// exception为null时，表示银企中间件正常响应，请解析body
			PaymentDetail[] reDetails = responsebody.getDetails();
			String[][] entrys_param = new String[reDetails.length][5];
			ISubstitutingEntry coll = SubstitutingEntryFactory.getLocalInstance(ctx);
			for (int h = 0; h < reDetails.length; h++) {
				PaymentDetail detail = reDetails[h];
				// 业务系统用于标识一笔支付的唯一ID，不能重复
				entrys_param[h][0]=detail.getDetailSeqID();		
				SubstitutingEntryInfo subentry=coll.getSubstitutingEntryInfo("where SERIALNUMBER='"+entrys_param[h][0]+"'");
				if(subentry.getBankStatus().equals(BankPayingBillStateEnum.TS) || subentry.getBankStatus().equals(BankPayingBillStateEnum.TF)){ 
					continue;
				}
				//  EB_PROCESSING:银企中间件处理中;EB_TRANSMIT_FAIL:银企中间件转发失败;BANK_PROCESSING:银行处理中 ;
				//BANK_SUCCESS:银行交易成功;BANK_FAIL:银行交易失败;BANK_EXCEPTION:银行交易异常
				entrys_param[h][1]=detail.getEbStatus();
				// 银企中间件对支付结果的描述
				entrys_param[h][2]=detail.getEbStatusMsg();
				// 银行提供的支付结果的状态码
				entrys_param[h][3]=detail.getBankStatus();
				// 银行提供的支付结果的描述信息
				entrys_param[h][4]=detail.getBankStatusMsg();
				//更新主表实发金额,实发笔数
				//更新分录银行状态,银行返回信息,是否成功
				BankPayingBillStateEnum state = null;
				boolean isSuccess = false;
				//扣款状态
				if("".equals(entrys_param[h][1])){
					//批扣已发起
					state=BankPayingBillStateEnum.DE;
				} else if ("EB_PROCESSING".equals(entrys_param[h][1])){
					//准备提交
					state=BankPayingBillStateEnum.OS;
				} else if ("BANK_PROCESSING".equals(entrys_param[h][1])){
					//提交成功
					state=BankPayingBillStateEnum.OS;
				} else if ("BANK_SUCCESS".equals(entrys_param[h][1])){
					//交易成功
					state=BankPayingBillStateEnum.TS;
					isSuccess = true;
				} else if ("BANK_FAIL".equals(entrys_param[h][1])){
					//交易失败
					state=BankPayingBillStateEnum.TF;
				} else if ("BANK_EXCEPTION".equals(entrys_param[h][1])){
					//交易未确认
					state=BankPayingBillStateEnum.NC;
				} else if ("EB_TRANSMIT_FAIL".equals(entrys_param[h][1])){
					//提交失败
					state=BankPayingBillStateEnum.OF;
				} 
				Connection conn = null;
				PreparedStatement pstmt = null;
				try {
					conn = getConnection(ctx);
					//更新分录银行状态和银行返回信息，并且更新是否成功字段
					String sql = "Update CT_YQ_SubstitutingEntry set CFBankStatus = ?,CFBankReturnInfo = ?,CFIsSucceed = ? where CFSERIALNUMBER  = ? ";
					pstmt = conn.prepareStatement(sql);
					pstmt.setInt(1, state.getValue());
					pstmt.setString(2, entrys_param[h][4]+entrys_param[h][3]+entrys_param[h][2]);
					pstmt.setBoolean(3, isSuccess);
					pstmt.setString(4, entrys_param[h][0]);
					pstmt.executeUpdate();
				} catch (SQLException e) {
					logger.info("Substituting info:QueryPay BatchSeqID "+serialNumber+ ",更新银行状态时失败！");
				} finally {
					SQLUtils.cleanup(null, pstmt, conn);
				}
			}
			//主要是为跨行调用接口后，重新加载实体，因为实体中分录的状态，和银行返回信息，和流水号已经保存
			EntityViewInfo view = filterViewToAll(bill.getId().toString());
			SubstitutingInfo info=isub.getSubstitutingCollection(view).get(0);
			//更新代发单实发金额和实发总数，并更新是否成功字段
			reverseSourceBill(ctx,info);
			//电脑IP
			InetAddress addr=null;
			try {
				addr = InetAddress.getLocalHost();
			} catch (UnknownHostException e1) {
				e1.printStackTrace();
			}
			String ip=addr.getHostAddress().toString();
			//电脑名称
			String computerName=addr.getHostName().toString();
			subhelp.LogForAuxiliaryFunction(ctx, info, InterfaceTypeEnum.BACKMSG, null, auxiliaryFunctions,ip,computerName);
//			responsebody.getBatchSeqID();//报账号
//			responsebody.getTotalCount();//总笔数
//			responsebody.getTotalAmount();//总金额
//			responsebody.getVerifyField();//校验字段
		} else if (responsebody == null) {
			logger.info("Substituting info:QueryPay BatchSeqID "+serialNumber+ " send exception: "+exception.getMessage()+" ,and the time that happens is "+exception.getTime());			
		}
		if(exception!=null){
			logger.error("ICBC ISubstituting result error:"+exception.getMessage());//自动执行脚本不适合把异常抛至前台
		}
	}
	/**
	 * 描述：过滤条件
	 * 作者：mmw
	 * 创建日期：2012-12-7-上午09:34:43
	 * @param string
	 * @return
	 */
	private EntityViewInfo filterViewToAll(String id) {
		SubstitutingCollection collection=new SubstitutingCollection();
		FilterInfo filter=new FilterInfo();
		EntityViewInfo  view=new EntityViewInfo();
		filter.getFilterItems().add(new FilterItemInfo("id",id,CompareType.EQUALS));
		view.setFilter(filter);
		SelectorItemCollection sele = new SelectorItemCollection();
		sele.add("number");
		sele.add("batchNumber");
		sele.add("feeType.number");
		sele.add("entrys.detailNumber");
		sele.add("entrys.bankStatus");
		sele.add("entrys.bankReturnInfo");
		sele.add("entrys.amount");
	    view.setSelector(sele);
		return view;
	}
	/**
     * 描述：提交成功，更新代发单实发金额，实发笔数，分录是否成功
     * 作者：mmw
     * 创建日期：2012-10-23-下午02:46:36
     * @param ctx
     * @param info 代发单实体
     * @throws BOSException
     * @throws EASBizException
     */
    private void reverseSourceBill(Context ctx, SubstitutingInfo info)
    	throws BOSException, EASBizException{
		BigDecimal totalAmount = FMConstants.ZERO;
		int totalCount = 0;
		SubstitutingEntryCollection entrycoll = info.getEntrys();
		for(int i = 0;i<entrycoll.size();i++){
			SubstitutingEntryInfo substitutingEntry=entrycoll.get(i);
			//交易成功，则改写是否成功字段和主表实发金额和实发笔数
			if(BankPayingBillStateEnum.TS.equals(substitutingEntry.getBankStatus())){
				totalAmount=totalAmount.add(substitutingEntry.getAmount());
				totalCount++;
			}
		}
		//更新代发单的实发金额和实发笔数
		info.setFactAmount(totalAmount);
		info.setFactPenNumber(totalCount);
		SelectorItemCollection item =new SelectorItemCollection();
		item.add(new SelectorItemInfo("factAmount"));
		item.add(new SelectorItemInfo("factPenNumber"));
		SubstitutingFactory.getLocalInstance(ctx).updatePartial(info, item);
	}
	/**
	 * 取批扣银企平台地址
	 * @param ctx
	 * @return String
	 */
	private String getEBServiceURL(Context ctx) {
		String url = "http://192.168.17.186:5289/services/EBService";
		try {
			ParameterConfigInfo pcInfo = ParameterConfigFactory.getLocalInstance(ctx).getParameterConfigInfo(" where number ='" +ConstantValueUtil.EBSERVICE703_URL+ "'");
			if(pcInfo != null && pcInfo.getValue() != null){
				url = pcInfo.getValue();
			}
		} catch (EASBizException e) {
			logger.error("Substituting error:getEBServiceURL error "+e.getLocalizedMessage(),e);//自动执行脚本不适合把异常抛至前台
		} catch (BOSException e) {
			logger.error("Substituting errot:getEBServiceURL error "+e.getLocalizedMessage(),e);//自动执行脚本不适合把异常抛至前台
		}
		return url;
	}
	/**
	 * 描述：按单据同步状态
	 * 作者：mmw
	 * 创建日期：2012-10-19-下午03:30:06
	 * @param ctx
	 * @param ids代发单集合
	 */
	private void syncBankAgentPayStateByBill(Context ctx, List ids) 
		throws BOSException,EASBizException {
		EntityViewInfo ev = new EntityViewInfo();
		FilterInfo filter = new FilterInfo();
		filter.getFilterItems().add(new FilterItemInfo("id", new HashSet(ids),CompareType.INCLUDE));
		ev.setFilter(filter);
		ev.getSelector().add("*");
		ev.getSelector().add("entrys.*");
		ev.getSelector().add("feeType.number");
		ev.getSelector().add("payBankNumber.*");
		ev.getSelector().add("payBankNumber.openArea.*");
		ev.getSelector().add("payBankNumber.bankInterfaceType");
		ev.getSelector().add("entrys.SettlementType.*");
		SubHelp subhelp=new SubHelp();
		SubstitutingCollection billColl = SubstitutingFactory.getLocalInstance(ctx).getSubstitutingCollection(ev);
		BankAcnt payBankAcnt = null;
		String packageID = null;
		//日志接口
		IBankLogFacade bankLogFacade = BankLogFacadeFactory.getLocalInstance(ctx);
		// 对 每一个账户循环更新
		for (int i = 0, size = billColl.size(); i < size; i++) {
			SubstitutingInfo bill = billColl.get(i);
			//"交易成功，交易失败,准备提交状态的的银行代发单不允许同步状态！
			//若分录中没有一条银行状态满足条件，则不需要掉用一下接口,若有则返回false
			if(checkEntryPayState(bill)) return;
			AccountBankInfo accountBankInfo = null;
			accountBankInfo = bill.getPayBankNumber();//付款账号
			BankInterfaceTypeEnum bankInterface = accountBankInfo.getBankInterfaceType();//银行接口
			payBankAcnt = new BankAcnt();
			payBankAcnt.setBank(bankInterface.getAlias());
			payBankAcnt.setAcntNumber(accountBankInfo.getBankAccountNumber());
			payBankAcnt.setAcntName(accountBankInfo.getAcctName());
			// R090616-165 多证书版本时传递“银行版本”“银行证书”给网关
			BankFacadeHelper.setBankAccountVersionAndCert(ctx, accountBankInfo,payBankAcnt);

			if (accountBankInfo.getOpenArea() != null) {
				payBankAcnt.setProvince(accountBankInfo.getOpenArea().getProvince());
				payBankAcnt.setCity(accountBankInfo.getOpenArea().getName());
				// todo: 添加几行 设置付款账户的brankId;
				payBankAcnt.setBranchID(accountBankInfo.getOpenArea().getNumber());
				payBankAcnt.setDeptID(accountBankInfo.getOpenArea().getDeptID());
			}
			//"交易成功，交易失败状态的的银行代发单不允许同步状态！
			//若分录满足条件的记录在list集合中
			List list=getEntryPayState(bill);
			//工资跨行付款/亲情1+1跨行付款/代收货款---调用付款单对私对公批量按单据同步接口
			PayStateInfo[] PayStateInfoColl;
			PayStateInfo info=null;
			int type=0;
			IObjectPK pk = null;
			//代发单辅助功能接口
			IAuxiliaryFunction auxiliaryFunction = AuxiliaryFunctionFactory.getLocalInstance(ctx);
			String feeTypeNumber=bill.getFeeType().getNumber();//收付类别编码
			if (feeTypeNumber.equals(ConstantValueUtil.WAGES) ||
					feeTypeNumber.equals(ConstantValueUtil.KINGSHIPBILL)) {
				//工资同行付款/亲情1+1同行付款--调用代发单对私批量按单据同步接口
				try {
					String[] packageIds = new String[list.size()];
					for (int j = 0; j < list.size(); j++) {
						packageIds[j] = ((SubstitutingEntryInfo)list.get(j)).getSerialNumber();
					}
					BankBatchSalaryService bankBatchSalaryService = new BankBatchSalaryService(ctx);
					//调用按单据同步状态接口
					PayStateInfoColl = bankBatchSalaryService.getSalaryPaymentState(createCaller(), payBankAcnt, packageIds);
					if (PayStateInfoColl == null) {
						continue;
					}
					// 暂时只取一个返回值，要么全部成功，要么全部失败
					for (int r = 0; r < list.size(); r++){
						SubstitutingEntryInfo entryinfo=(SubstitutingEntryInfo) list.get(r);
						BankPayingBillStateEnum state = FmBeHelper.transferState(((PayStateInfo)PayStateInfoColl[r]).getPaymentState());
						entryinfo.setBankStatus(state);
						String returnMsg = ((PayStateInfo)PayStateInfoColl[r]).getReturnMessage();
						entryinfo.setBankReturnInfo(returnMsg);
						//反写上游单据付款状态及更新代发单数据
						reverseSourceBillState(ctx, entryinfo);
						//提交银企互联成功时记录在代发单辅助功能中
				        subhelp.LogForAuxiliaryFunction(ctx, bill, InterfaceTypeEnum.BACKMSG,entryinfo,auxiliaryFunction,"","");
					}
				} catch (Exception e) {
					logger.error("(定时自动任务的按单据同步状态)sync Substituting failure! exception message is:",e);
					e.printStackTrace();
				}
			}else if(feeTypeNumber.equals(ConstantValueUtil.WAGESN) ||
						feeTypeNumber.equals(ConstantValueUtil.KINGSHIPBILLN) ||
						feeTypeNumber.equals(ConstantValueUtil.REMITREFUNDBILL)){
					//工资跨行付款/亲情1+1跨行付款/代收货款---调用付款单对私对公批量按单据同步接口
			try{
				String[] packageIds = new String[1];
				AccountBankFactory settlementTypeSettlementTypeFactory;
				ISettlementType settlementTypecoll = SettlementTypeFactory.getLocalInstance(ctx);
				for (int k = 0; k < list.size(); k++) {
					SubstitutingEntryInfo entryInfo=(SubstitutingEntryInfo) list.get(k);
					packageIds[0] = ((SubstitutingEntryInfo)list.get(k)).getSerialNumber();
					//生成银企日志，返回主键pk
					pk = bankLogFacade.buildPayStateSend(entryInfo.getSettlementType().isIsPersonPay(), payBankAcnt, packageIds, accountBankInfo);
					
					//如果是对公付款，则调用接口getPaymentState,如果是对私付款，则调用接口getPaymentStatePrivate
					SettlementTypeInfo settlementTypeinfo=settlementTypecoll.getSettlementTypeInfo(new ObjectUuidPK(entryInfo.getSettlementType().getId()));
					if(!settlementTypeinfo.isIsPersonPay()){
						BankServiceUtil bankServiceUtil = new BankServiceUtil(ctx);
						PayStateInfoColl =bankServiceUtil.getPaymentState(createCaller(), payBankAcnt, packageIds); 
					}else{	
						BankPrivateService bankPrivateUtil = new BankPrivateService(ctx);
						PayStateInfoColl = bankPrivateUtil.getPaymentStatePrivate(createCaller(), payBankAcnt, packageIds);
					}
					type = 1;
					if (PayStateInfoColl == null) {
						continue;
					}
					
					//根据主键pk更新银企日志
					bankLogFacade.buildPayStateReceive(pk, info);
					BankPayingBillStateEnum returnMsgstate = FmBeHelper.transferState(((PayStateInfo)PayStateInfoColl[0]).getPaymentState());
					String returnMsg = ((PayStateInfo)PayStateInfoColl[0]).getReturnMessage();
					entryInfo.setBankStatus(returnMsgstate);
					entryInfo.setBankReturnInfo(returnMsg);
					//修改分录的银行状态，银行返回信息，若交易成功则实发金额，实发笔数，
					reverseSourceBillState(ctx,entryInfo);
					//提交银企互联成功时记录在代发单辅助功能中
			        subhelp.LogForAuxiliaryFunction(ctx, bill, InterfaceTypeEnum.BACKMSG,entryInfo,auxiliaryFunction,"","");
				}
			}catch (Exception e) {
				logger.error("(定时自动任务的按单据同步状态)sync Substituting failure! exception message is:",e);
				//根据主键pk更新银企日志
				bankLogFacade.buildException(pk, e, type);
				e.printStackTrace();
			}
		}
		}
	}
		/**
		 * 描述:更新代发单主表和分录的数据
		 * @param ctx
		 * @param info代发单分录id集合
		 * @throws BOSException
		 * @throws EASBizException
		 */
		private void reverseSourceBillState(Context ctx, SubstitutingEntryInfo info) 
				throws BOSException, EASBizException {
			BankPayingBillStateEnum state = info.getBankStatus();
			//更新主表实发金额,实发笔数
			//更新分录银行状态,银行返回信息,是否成功
			Connection conn = null;
			PreparedStatement pstmt = null;
			try {
				conn = getConnection(ctx);
				//更新主表代发单
				String sql = "Update CT_YQ_Substituting SET CFFactAmount= CFFactAmount + ?,CFFactPenNumber=CFFactPenNumber + ? where fid  = ? ";
				pstmt = conn.prepareStatement(sql);
				boolean isSuccess = false;
				//银行状态交易成功的情况
				if (state.equals(BankPayingBillStateEnum.TS)){
					isSuccess = true;
					pstmt.setBigDecimal(1, info.getAmount());
					pstmt.setInt(2,1);
				}else{
					isSuccess = false;
					pstmt.setBigDecimal(1, FMConstants.ZERO);
					pstmt.setInt(2, FMConstants.INT_ZERO);
				}
				pstmt.setString(3, info.getParent().getId().toString());
				pstmt.executeUpdate();
				//更新分录状态
				sql = "Update CT_YQ_SubstitutingEntry set CFBankStatus = ?,CFBankReturnInfo = ?,CFIsSucceed = ? where fid  = ? ";
				pstmt = conn.prepareStatement(sql);
				pstmt.setInt(1, state.getValue());
				pstmt.setString(2, info.getBankReturnInfo());
				pstmt.setBoolean(3, isSuccess);
				pstmt.setString(4, info.getId().toString());
				pstmt.executeUpdate();
			} catch (SQLException e) {
				throw new BEException(BEException.WRITESTATEFAILURE);
			} finally {
				SQLUtils.cleanup(null, pstmt, conn);
			}
		}
		/**
		 * 描述：//若分录满足条件的记录在list集合中
		 * 作者：mmw
		 * 创建日期：2012-10-19-上午10:41:46
		 * @param bill代发单
		 * @return
		 */
		private List getEntryPayState(SubstitutingInfo bill) {
			List list=new ArrayList();
			for (int i = 0; i < bill.getEntrys().size(); i++) {
				BankPayingBillStateEnum state=((SubstitutingEntryInfo)(bill.getEntrys().get(i))).getBankStatus();
				//交易未确认，提交失败，提交成功，允许同步状态
				if (state==BankPayingBillStateEnum.NC || state==BankPayingBillStateEnum.OF || state==BankPayingBillStateEnum.OS){
					list.add(bill.getEntrys().get(i));
				}
			}
			return list;
		}
		/**
		 * 描述：检查分录中的银行状态是否有’交易未确认‘，有则返回false
		 * 准备提交，交易成功，交易失败状态的的银行代发单不允许同步状态！
		 * @param bill
		 * @return
		 */
		private boolean checkEntryPayState(SubstitutingInfo bill) {
			for (int i = 0; i < bill.getEntrys().size(); i++) {
				BankPayingBillStateEnum state=((SubstitutingEntryInfo)(bill.getEntrys().get(i))).getBankStatus();
				//准备提交,交易未确认，提交失败，提交成功，允许同步状态
				if (state==BankPayingBillStateEnum.NC || state==BankPayingBillStateEnum.OF || state==BankPayingBillStateEnum.OS || state==BankPayingBillStateEnum.OP){
					return false;
				}
			}
			return true;
		}
		/**
		 * 描述：接口连接参数
		 * @return
		 */
		private  CallerTag createCaller(){
			CallerTag caller = new CallerTag();
			caller.setCaller("Jason");
			caller.setIp("127.0.0.1");
			caller.setOs("EAS");
			caller.setVersion("6.0");
			caller.setTime(new Date());
			return caller;
		}
}